package com.mindskip.xzs.configuration.spring.security;
//一个在用户认证成功后的处理逻辑：
//在用户认证成功后，通过依赖注入的方式初始化 eventPublisher 和 userService。
//获取认证主体信息，将其转换为 Spring Security 的 User 对象。
//根据用户名从数据库中获取用户信息。
//创建用户事件日志对象，并设置日志内容。
//发布用户登录事件，将用户事件日志对象传递给事件发布者。
//创建新的用户对象，设置用户名和用户头像路径。
//返回成功响应，包含用户信息。
//如果认证主体为空，返回未授权响应。
//前端通过调用后端的认证接口进行用户登录认证。
//在用户认证成功后，后端会执行该代码，处理用户认证成功后的逻辑，包括发布用户登录事件和返回用户信息。
//后端接收前端发送的认证请求，验证用户身份信息。
//在用户认证成功后，执行该代码逻辑，处理用户认证成功后的事务，包括发布用户登录事件和返回用户信息。
import com.mindskip.xzs.base.SystemCode;
import com.mindskip.xzs.domain.UserEventLog;
import com.mindskip.xzs.event.UserEvent;
import com.mindskip.xzs.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;

/**
 * RestAuthenticationSuccessHandler 继承自 SimpleUrlAuthenticationSuccessHandler
 * 这是一个 Spring 组件，用于处理用户认证成功后的逻辑
 */
@Component
public class RestAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {

    private final ApplicationEventPublisher eventPublisher; // 发布事件的组件
    private final UserService userService; // 用户服务，提供获取用户信息等功能

    /**
     * 构造函数，通过依赖注入初始化 eventPublisher 和 userService
     * @param eventPublisher 事件发布者
     * @param userService 用户服务
     */
    @Autowired
    public RestAuthenticationSuccessHandler(ApplicationEventPublisher eventPublisher, UserService userService) {
        this.eventPublisher = eventPublisher;
        this.userService = userService;
    }

    /**
     * 处理用户认证成功后的逻辑
     * @param request HTTP 请求
     * @param response HTTP 响应
     * @param authentication 认证信息
     */
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
        Object object = authentication.getPrincipal(); // 获取认证主体
        if (null != object) {
            // 如果认证主体不为空，进行以下处理
            User springUser = (User) object; // 将认证主体转换为 Spring Security 的 User 对象
            com.mindskip.xzs.domain.User user = userService.getUserByUserName(springUser.getUsername()); // 通过用户名从数据库获取用户信息
            if (null != user) {
                // 如果用户信息不为空，进行以下处理
                UserEventLog userEventLog = new UserEventLog(user.getId(), user.getUserName(), user.getRealName(), new Date()); // 创建用户事件日志
                userEventLog.setContent(user.getUserName() + " 登录了学之思开源考试系统"); // 设置日志内容
                eventPublisher.publishEvent(new UserEvent(userEventLog)); // 发布用户登录事件
                com.mindskip.xzs.domain.User newUser = new com.mindskip.xzs.domain.User(); // 创建新的用户对象
                newUser.setUserName(user.getUserName()); // 设置用户名
                newUser.setImagePath(user.getImagePath()); // 设置用户头像路径
                RestUtil.response(response, SystemCode.OK.getCode(), SystemCode.OK.getMessage(), newUser); // 返回成功响应，包含用户信息
            }
        } else {
            // 如果认证主体为空，返回未授权响应
            RestUtil.response(response, SystemCode.UNAUTHORIZED.getCode(), SystemCode.UNAUTHORIZED.getMessage());
        }
    }
}
